home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / DDJ0192.ARJ / RAID.ASC < prev    next >
Text File  |  1991-11-21  |  14KB  |  592 lines

  1. _THE FIVE LEVELS OF RAID_
  2. by Mike Wiebel and Steve Johnson
  3.  
  4. [LISTING ONE]
  5.  
  6.  
  7.  /* sled.c */
  8.  
  9. #include <stdio.h>
  10. #include <assert.h>
  11. #include <csimdefs.h>
  12.  
  13. #define HMSEC(x)        ((TIME)((x)))                   /* 1.0e-05 second */
  14. #define MSEC(x)         ((TIME)(100.0 * (x)))           /* milli second */
  15. #define SEC(x)          MSEC((1000.0 * (x)))            /* second */
  16. #define MINUTE(x)       SEC((60.0 * (x)))               /* minute */
  17. #define HOUR(x)         MINUTE((60.0 * (x)))
  18.  
  19. #define NUM_DISKS    1    /* num. disks in simulation */
  20. #define NUM_FE        1L    /* num. front end channels */
  21. #define NUM_BE        1L    /* num. back end channels */
  22. #define SEEK_TIME    3.83    /* avg. num. of milliseconds spent seeking */
  23. #define LATENCY        14.22    /* milliseconds required for one rotation */
  24. #define NUM_CYLINDERS    1113    /* num. cylinders on disk */
  25. #define TRACKS_PER_CYL    15     /* num. tracks per cylinder */
  26.  
  27. SS_PTR     cu;        /* CSIM control unit pointer       */
  28. SS_PTR     disk_drive;    /* CSIM disk drive pointer         */
  29. MS_PTR     fe_bus;        /* CSIM front end channel pointer  */
  30. MS_PTR  be_bus;        /* CSIM back end channel pointer   */
  31.  
  32. static long track=0L;    /* current track backing */
  33. static int cylinder=0;  /* current cylinder backing */
  34. static long tot_tracks=0L; /* total tracks backed */
  35.  
  36. void backup_status(done)
  37. int *done;
  38. {
  39.  
  40.     /* determine if this disk drive is backed up. */
  41.  
  42.     track++;
  43.     tot_tracks++;
  44.     if (tot_tracks == NUM_DISKS * NUM_CYLINDERS * TRACKS_PER_CYL)
  45.         *done = 1;
  46. }
  47.  
  48. ECODE seek()
  49. {
  50. long    num_fe; /* num. front end channels available */
  51.  
  52.     if(track == 1){    /* first track requires seek */
  53.         XacAdvExponen(MSEC(SEEK_TIME));
  54.     }
  55.     if(track == TRACKS_PER_CYL){
  56.         XacAdvance(MSEC(LATENCY));/* switch cylinder and rotate */
  57.         track = 0;
  58.         cylinder++;
  59.     }
  60.  
  61.     /* if channel is available transmit data; else rotational delay */
  62.  
  63.     MAvail(fe_bus,&num_fe);
  64.     while(!num_fe){
  65.         XacAdvance(MSEC(LATENCY));
  66.         MAvail(fe_bus,&num_fe);
  67.  
  68.  
  69.                 /* sled.c - 2 */
  70.     }
  71.     return(SUCCESS);
  72. }
  73.  
  74. ECODE send_data()
  75. {
  76. double xfr_time;
  77.  
  78.     /* transfer data back to host */
  79.  
  80.     xfr_time = LATENCY;
  81.     MSeize(fe_bus,1L);
  82.     XacAdvance(MSEC(xfr_time));
  83.     MRelease(fe_bus,1L);
  84.     return(SUCCESS);
  85. }
  86.  
  87. int sim_main(argc, argv)
  88. int argc;
  89. char *argv[];
  90. {
  91. int     done=0;
  92. int     i;
  93.  
  94.     /* configure system and set up CSIM statistics */
  95.  
  96.     SServer(&cu,"control unit statistics");
  97.     SServer(&disk_drive,"disk drive statistics");
  98.     MServer(&fe_bus,NUM_FE,"front end channels");
  99.     MServer(&be_bus,NUM_BE,"back end channels");
  100.  
  101.     /* set simulation time */
  102.  
  103.     SimWarmUp(0,0);
  104.     SimRun(MINUTE(30),1);
  105.  
  106.     /* simulate backup */    
  107.  
  108.     SSeize(disk_drive);
  109.     SSeize(cu);
  110.     MSeize(be_bus,1L);
  111.     for(i=0; i<NUM_DISKS; i++){
  112.         do{
  113.             backup_status(&done);    
  114.             assert(seek() == SUCCESS);
  115.             assert(send_data() == SUCCESS);
  116.         }while(!done);
  117.         done = 0;
  118.         track = 0;
  119.     }
  120.     printf("Backup complete\n");
  121.     SimPrint();
  122.     SRelease(cu);
  123.     MRelease(be_bus,1L);
  124.     SRelease(disk_drive);
  125.     XacTerminate();
  126. }
  127.  
  128.  
  129. [LISTING TWO]
  130.  
  131.  /* RAID level 1 */
  132. #include <stdio.h>
  133. #include <assert.h>
  134. #include <csimdefs.h>
  135.  
  136. #define HMSEC(x)        ((TIME)((x)))                   /* hund.milli second */
  137. #define MSEC(x)         ((TIME)(100.0 * (x)))           /* milli second */
  138. #define SEC(x)          MSEC((1000.0 * (x)))            /* seconds */
  139. #define MINUTE(x)       SEC((60.0 * (x)))               /* minutes */
  140. #define HOUR(x)         MINUTE((60.0 * (x)))
  141.  
  142. #define NUM_DISKS       1    /* one disk; other disk is mirror */
  143. #define NUM_FE          2L      /* num. front end channels */
  144. #define NUM_BE          2L      /* num. back end channels */
  145. #define NUM_CU        2L    /* num. of control units */
  146. #define SEEK_TIME       3.83    /* avg. num. of milliseconds spent seeking */
  147. #define LATENCY         14.22   /* avg. num. milliseconds spent seeking */
  148. #define NUM_CYLINDERS   2226
  149. #define TRACKS_PER_CYL  15
  150.  
  151. MS_PTR  cu;             /* CSIM control unit pointer */
  152. MS_PTR  disk_drive;     /* CSIM disk drive pointer   */
  153. MS_PTR  fe_bus;         /* CSIM front end channel pointer */
  154. MS_PTR  be_bus;         /* CSIM back end channel pointer */
  155. Q_PTR    tsend;
  156.  
  157. static long track=0L;
  158. static int curr_cylinder=0;
  159.  
  160. void backup_status(done)
  161. int *done;
  162. {
  163.         /* determine if this disk drive is backed up. */
  164.  
  165.     track++;
  166.     if (track == TRACKS_PER_CYL){
  167.         track = 0;
  168.         curr_cylinder++;
  169.     }
  170.         if (curr_cylinder == NUM_CYLINDERS * NUM_DISKS)
  171.                 *done = 1;
  172. }
  173.  
  174. ECODE seek(cylinder_backing)
  175. int *cylinder_backing;
  176. {
  177. long    num_fe;
  178.  
  179.         if(curr_cylinder == 0 && track == 1){    /* first track requires seek */
  180.                 XacAdvExponen(MSEC(SEEK_TIME));
  181.         }
  182.         if(*cylinder_backing != curr_cylinder){
  183.                 XacAdvance(MSEC(LATENCY));
  184.         *cylinder_backing = curr_cylinder; 
  185.         }
  186.         return(SUCCESS);
  187. }
  188.  
  189.  
  190.  
  191.  
  192.                    /*   lvl1.c - 2   */
  193.  
  194. ECODE send_data()
  195. {
  196. double xfr_time;
  197.  
  198.  
  199.     /* transfer data back to host */
  200.     xfr_time = LATENCY;
  201.  
  202.     MSeize(fe_bus,1L);
  203.         XacAdvance(MSEC(xfr_time));
  204.     MRelease(fe_bus,1L);
  205.         return(SUCCESS);
  206. }
  207.  
  208. int sim_main(argc, argv)
  209. int argc;
  210. char *argv[];
  211. {
  212. XAC_PTR xp;
  213. BOOLEAN orig;
  214. static int done=0;
  215. int cylinder_backing=0;
  216. int i;
  217.  
  218. /* configure system and set up CSIM utilities */
  219.     MServer(&disk_drive,2L,"Disk drive server statistics");
  220.     MServer(&cu,NUM_CU,"Control unit server statistics");
  221.     MServer(&fe_bus,NUM_FE,"front end channel statistics");
  222.     MServer(&be_bus,NUM_BE,"back end channel statistics");
  223.     Queue(&tsend,"Time to send data");
  224.  /* set simulation time */
  225.         SimWarmUp(0,0);
  226.         SimRun(MINUTE(17),1);
  227. /* simulate backup */
  228.     XacSplit(&xp,&orig);    /* allow each disk subsys to transfer */
  229.     MSeize(cu,1L);
  230.     MSeize(be_bus,1L);
  231.     MSeize(disk_drive,1L);
  232.         for(i=0; i<NUM_DISKS; i++){
  233.                 do{
  234.                         assert(seek(&cylinder_backing)==SUCCESS);
  235.             QEnter(tsend);
  236.                         assert(send_data()==SUCCESS);
  237.             QLeave(tsend);
  238.                         backup_status(&done);
  239.                 }while(!done);
  240.                 done = 0;
  241.                 track = 0;
  242.         }
  243.     SimPrint();
  244.         MRelease(cu,1L);
  245.         MRelease(be_bus,1L);
  246.         MRelease(disk_drive,1L);
  247.         XacTerminate();
  248. }
  249.  
  250.  
  251. [LISTING THREE]
  252.  
  253.  /* RAID level 3 */
  254.  
  255. #include <stdio.h>
  256. #include <csimdefs.h>
  257.  
  258. #define HMSEC(x)        ((TIME)((x)))                   /* 1.0e-05 second */
  259. #define MSEC(x)         ((TIME)(100.0 * (x)))           /* milli second */
  260. #define SEC(x)          MSEC((1000.0 * (x)))            /* second */
  261. #define MINUTE(x)       SEC((60.0 * (x)))               /* minute */
  262. #define HOUR(x)         MINUTE((60.0 * (x)))
  263.  
  264. #define GRP_SIZE    4    /* no. data disks in parity group */
  265. #define NUM_CHECK    1    /* no. check disks in group */
  266. #define NUM_CHAN    2L    /* no. of channels */
  267. #define NUM_BUSS    5L    /* no. busses */
  268. #define SEEK_TIME       11.5    /* avg. num. of milliseconds spent seeking */
  269. #define LATENCY         16.66   /* milliseconds required for one rotation */
  270. #define TRACK_CAPACITY  40.0    /* capacity in KB */
  271. #define XFR_RATE       10000.0  /* KB transferred per sec */
  272. #define NUM_CYLINDERS   1900    /* no. useable cylinders on device */
  273. #define TRACKS_PER_CYL  19    /* no. tracks per cylinder */
  274. #define SWITCH_TIME     4    /* milliseconds */
  275.  
  276. SS_PTR     raid_cu;    /* CSIM RAID control unit pointer */
  277. MS_PTR    data_disk;    /* CSIM array of data disks pointer */
  278. SS_PTR    check_disk;    /* CSIM check disk pointer */
  279. MS_PTR    buss;        /* CSIM array of busses pointer */
  280. MS_PTR    channel;    /* CSIM array of channels pointer */
  281.  
  282.  
  283. ECODE seek(track_tally,original,track_count)
  284. long track_tally;
  285. BOOLEAN    original;
  286. int *track_count;
  287. {
  288.  
  289.     if (original){
  290.         SSeize(check_disk);
  291.     }
  292.     else{
  293.         MSeize(data_disk,1L);
  294.     }
  295.     if (!track_tally){
  296.         XacAdvExponen(MSEC(SEEK_TIME));
  297.     }
  298.     if (!(*track_count) && track_tally){/* switch cylinders */    
  299.         XacAdvance(MSEC(SWITCH_TIME));
  300.     }
  301.     (*track_count)++;
  302.     if (*track_count == TRACKS_PER_CYL)
  303.         *track_count = 0;
  304.  
  305.     if (original){
  306.         SRelease(check_disk);
  307.     }
  308.     else{
  309.         MRelease(data_disk,1L);
  310.     }
  311.     return(SUCCESS);
  312. }
  313.  
  314.                  /* lvl3.c - 2  */
  315.  
  316. ECODE transfer()
  317. {
  318. double xfr_time;
  319. XAC_PTR    xp;
  320. BOOLEAN orig;
  321.  
  322.     /* send data to control unit */
  323.  
  324.     MSeize(buss,1L);
  325.     XacAdvance(MSEC(LATENCY));
  326.     MRelease(buss,1L);
  327.  
  328.     /* send data to host */
  329.  
  330.     XacSplit(&xp,&orig);
  331.     if (!orig){
  332.         xfr_time = TRACK_CAPACITY/XFR_RATE;
  333.         MSeize(channel,1L);
  334.         XacAdvance(SEC(xfr_time));
  335.         MRelease(channel,1L);
  336.         XacTerminate();
  337.     } 
  338.     return(SUCCESS);
  339. }
  340.  
  341. int sim_main(argc, argv)
  342. int argc;
  343. char *argv[];
  344. {
  345. static     int     done=0;        /* flag indicating completion */
  346. int     track_count=0;
  347. long     track_tally=0;        /* count of tracks backed up */
  348. long     backup_goal;         /* total number of tracks to back up */
  349. int     i;            /* counter */
  350. XAC_PTR xp;            /* CSIM transaction pointer */
  351. BOOLEAN    original;        /* flag indicating presence of original xac */
  352.  
  353.     /* configure system and set up CSIM */
  354.  
  355.     SServer(&raid_cu,"Control unit server statistics");
  356.     SServer(&check_disk,"check disk statistics");
  357.     MServer(&data_disk,GRP_SIZE,"data disk statistics");
  358.     MServer(&buss,NUM_BUSS,"buss statistics");
  359.     MServer(&channel,NUM_CHAN,"channel statistics");
  360.  
  361.     /* set simulation period */
  362.  
  363.     SimWarmUp(0,0);
  364.     SimRun(MINUTE(30),1);
  365.     
  366.     for(i=0; i<GRP_SIZE; i++){         /* generate xac for each disk */
  367.         XacSplit(&xp,&original);
  368.         if (!original)
  369.             break;
  370.     }
  371.  
  372.     /* backup subsystem */
  373.  
  374.  
  375.                    /* lvl3.c - 3 */
  376.  
  377.     backup_goal = TRACKS_PER_CYL * NUM_CYLINDERS;
  378.     while(!done){
  379.         seek(track_tally,original,&track_count);
  380.         transfer();
  381.         track_tally++;
  382.         if (track_tally == backup_goal){
  383.             done = 1;
  384.             SimPrint();
  385.         }
  386.     }
  387.     XacTerminate();
  388. }
  389.  
  390.  
  391.  
  392. [LISTING FOUR]
  393.  
  394.  /* RAID level 5 */
  395.  
  396. #include <stdio.h>
  397. #include <assert.h>
  398. #include <csimdefs.h>
  399.  
  400. #define HMSEC(x)        ((TIME)((x)))                   /* 1.0e-05 second */
  401. #define MSEC(x)         ((TIME)(100.0 * (x)))           /* milli second */
  402. #define SEC(x)          MSEC((1000.0 * (x)))            /* second */
  403. #define MINUTE(x)       SEC((60.0 * (x)))               /* minute */
  404. #define HOUR(x)         MINUTE((60.0 * (x)))
  405.  
  406. #define GRP_SIZE    50    /* no. data disks in parity group */
  407. #define NUM_CHAN    2L    /* no. of channels */
  408. #define NUM_BUSS    50L    /* no. busses */
  409. #define SEEK_TIME       11.5    /* avg. num. of milliseconds spent seeking */
  410. #define LATENCY         16.66   /* milliseconds required for one rotation */
  411. #define TRACK_CAPACITY  40.0    /* capacity in KB */
  412. #define XFR_RATE       10000.0  /* KB transferred per sec */
  413. #define NUM_CYLINDERS   1900    /* no. useable cylinders on device */
  414. #define TRACKS_PER_CYL  19    /* no. tracks per cylinder */
  415. #define SWITCH_TIME     4    /* milliseconds */
  416. #define BUF_SZ        50    /* number of tracks buffer will hold */
  417.  
  418. SS_PTR     raid_cu;    /* CSIM RAID control unit pointer */
  419. SAS_PTR    data_disk;    /* CSIM array of data disks pointer */
  420. MS_PTR    buss;        /* CSIM array of busses pointer */
  421. MS_PTR    channel;    /* CSIM array of channels pointer */
  422. long     buffer[BUF_SZ]; /* RAID control unit buffer */
  423. long     update[BUF_SZ]; /* RAID buffer lock */
  424. static  long last_buf=0L; /* last track written to buffer */
  425.  
  426. void buffer_search(track,bingo,slot)
  427. long track;
  428. int *bingo;
  429. int *slot;
  430. {
  431. int i;
  432.  
  433.         *bingo = 0;
  434.         for(i=0; i<BUF_SZ; i++)
  435.                 if(buffer[i] == track){
  436.                         *bingo = 1;
  437.                         *slot = i;
  438.                 }
  439. }
  440.  
  441. ECODE buf_get(slot)
  442. int slot;
  443. {
  444. double    xfer_time;
  445. XAC_PTR xp;
  446. BOOLEAN orig;
  447.  
  448.     xfer_time = TRACK_CAPACITY / (double)XFR_RATE;
  449.     XacSplit(&xp,&orig);
  450.     MSeize(channel,1L);
  451.     XacAdvance(SEC(xfer_time/2.0));
  452.     MRelease(channel,1L);
  453.  
  454.  
  455.                    /* lvl5.c - 2 */
  456.     if(!orig){
  457.         XacTerminate();
  458.     }
  459.     buffer[slot] = -1;    /* mark slot as writeable */
  460.     return(SUCCESS);
  461. }
  462.  
  463. int find_track(track)
  464. long track;
  465. {
  466. int number;
  467.  
  468.         number = track;
  469.         while(number >= GRP_SIZE)
  470.                 number -= GRP_SIZE;
  471.     return(number);
  472. }
  473.  
  474. ECODE track_get()
  475. {
  476.  
  477.     MSeize(buss,1L);
  478.     MSeize(channel,1L);
  479.     XacAdvance(MSEC(LATENCY));
  480.     XacAdvance(MSEC(1));
  481.     MRelease(channel,1L);
  482.     MRelease(buss,1L);
  483.     return(SUCCESS);
  484. }
  485.  
  486. ECODE update_buf(track)
  487. long track;
  488. {
  489. XAC_PTR    xp;
  490. BOOLEAN    orig;
  491. static int i;
  492. static int j;
  493. int slot;
  494. long next;
  495. int d_num;
  496.  
  497.     j = 0;
  498.     for(i=0; i<BUF_SZ; i++){
  499.         XacSplit(&xp,&orig);
  500.         if(!orig) break;
  501.     }
  502.     if(!orig){
  503.         slot = j++;
  504.         if(buffer[slot] < track && update[slot] != 1){
  505.             update[slot] = 1;
  506.             next = last_buf++;
  507.             d_num = find_track(next);
  508.             SASeize(data_disk,d_num);
  509.             XacAdvance(MSEC(LATENCY));
  510.             SARelease(data_disk,d_num);
  511.             buffer[slot] = next;
  512.             update[slot] = 0;
  513.         }
  514.  
  515.               /* lvl5.c - 3 */
  516.  
  517.         XacTerminate();
  518.     }
  519.     return(SUCCESS);
  520. }
  521.  
  522. int sim_main(argc, argv)
  523. int argc;
  524. char *argv[];
  525. {
  526. XAC_PTR xp;            /* CSIM transaction pointer */
  527. BOOLEAN    original;        /* flag indicating presence of original xac */
  528. static  int done=0;
  529. static  long track=0L;
  530. int     disk_num;
  531. int     i;
  532. int    slot;
  533. int    bingo;
  534. BOOLEAN avail;
  535.  
  536.     /* configure system and set up CSIM */
  537.  
  538.     SServer(&raid_cu,"Control unit buffer statistics");
  539.     SArray(&data_disk,GRP_SIZE,"data disk statistics");
  540.     MServer(&buss,NUM_BUSS,"buss statistics");
  541.     MServer(&channel,NUM_CHAN,"channel statistics");
  542.  
  543.     for(i=0; i<BUF_SZ; i++){ /* mark buffer as empty */
  544.         buffer[i] = -1;
  545.         update[i] = 0;
  546.     }
  547.  
  548.     /* set simulation period */
  549.  
  550.     SimWarmUp(0,0);
  551.     SimRun(MINUTE(30),1);
  552.     
  553.     while(!done){
  554.         XacSplit(&xp,&original);
  555.         if(original){
  556.             buffer_search(track,&bingo,&slot);
  557.             if(bingo){
  558.                 assert(buf_get(slot) == SUCCESS);
  559.             }
  560.             else{
  561.                 disk_num = find_track(track);
  562.                 SAAvail(data_disk,disk_num,&avail);
  563.                 SASeize(data_disk,disk_num);
  564.                 buffer_search(track,&bingo,&slot);
  565.                 if(bingo){
  566.                     assert(buf_get(slot) == SUCCESS);
  567.                 }
  568.                 else{
  569.                     assert(track_get() == SUCCESS);
  570.                 }
  571.                 SARelease(data_disk,disk_num);
  572.             }    
  573.  
  574.  
  575.                        /* lvl5.c - 3 */
  576.  
  577.             if (track == GRP_SIZE * TRACKS_PER_CYL * NUM_CYLINDERS)
  578.                                    done = 1;
  579.             track++;
  580.         } 
  581.         else{                /* maintain buffer */
  582.             assert(update_buf(track) == SUCCESS);
  583.             XacTerminate();
  584.         }
  585.     }
  586.     printf("Backup complete\n");
  587.     SimPrint();
  588. }
  589.  
  590.  
  591.  
  592.